//
//  yuvconvert.c
//  OSD_test
//
//  Created by gehj on 2023/2/10.
//

#include "yuvconvert.h"




/**
NV16(YUV422SP) -->YUV422 planar
 
yyyy yyyy
uv    uv
->
yyyy yyyy
uu
vv
*/

void NV16_to_YU16(unsigned char* yuv422sp,
                         unsigned char* yuv422p,
                         int width, int height)
{
    int i, j;
    int y_size;
    int uv_size;
    unsigned char* p_ysp;
    unsigned char* p_uv;
 
    unsigned char* p_yp;
    unsigned char* p_u;
    unsigned char* p_v;
    
    if(width <= 0 || height<= 0)
    {
        printf("width and height of background image must be greater than 0.\n");
        if (yuv422sp)
        {
            free(yuv422sp);
            yuv422sp = NULL;
        }
        if (yuv422p)
        {
            free(yuv422p);
            yuv422p = NULL;
        }
        exit (-1);
    }
    
    if (((width & 0x1) != 0) || ((height & 0x1) != 0))
    {
        printf("width and height of background image must be multiple of 2.\n");
        if (yuv422sp)
        {
            free(yuv422sp);
            yuv422sp = NULL;
        }
        if (yuv422p)
        {
            free(yuv422p);
            yuv422p = NULL;
        }
        exit (-1);
    }
    
    y_size = uv_size = width * height;
 
    p_ysp = yuv422sp;
    p_uv = yuv422sp + y_size;
 
    p_yp = yuv422p;
    p_u  = yuv422p + y_size;
    p_v  = p_u + width * height / 2;
 
    
    
    //y通道处理
    memcpy(p_yp, p_ysp, y_size);
    
    //uv通道处理 p_uv跳着进p_u或者p_v
    for (j = 0, i = 0; j < uv_size; j+=2, i++)
    {
        p_u[i] = p_uv[j];
        p_v[i] = p_uv[j+1];
    }
}

/**
NV61(YUV422SP) -->YUV422 planar(YV16)
 
yyyy yyyy
vu    vu
->
yyyy yyyy
vv
uu
*/
void NV61_to_YV16(unsigned char* yuv422sp,
                         unsigned char* yuv422p,
                         int width, int height)
{
    int i, j;
    int y_size;
    int uv_size;
    unsigned char* p_ysp;
    unsigned char* p_uv;
 
    unsigned char* p_yp;
    unsigned char* p_u;
    unsigned char* p_v;
    
    if(width <= 0 || height<= 0)
    {
        printf("width and height of background image must be greater than 0.\n");
        exit (-1);
    }
    
    if (((width & 0x1) != 0) || ((height & 0x1) != 0))
    {
        printf("width and height of background image must be multiple of 2.\n");
        exit (-1);
    }
    
    y_size = uv_size = width * height;
 
    p_ysp = yuv422sp;
    p_uv = yuv422sp + y_size;
 
    p_yp = yuv422p;
    p_v  = yuv422p + y_size;
    p_u  = p_v + width * height / 2;
 
    //y通道处理
    memcpy(p_yp, p_ysp, y_size);
    
    //uv通道处理 p_uv跳着进p_v或者p_u
    for (j = 0, i = 0; j < uv_size; j+=2, i++)
    {
        p_v[i] = p_uv[j];
        p_u[i] = p_uv[j+1];
    }
}



/**
YUV422 planar -->NV16(YUV422SP)
 
yyyy yyyy
uu
vv
->
yyyy yyyy
uv    uv
*/
void YU16_to_NV16(unsigned char* yuv422sp,
                         unsigned char* yuv422p,
                         int width, int height)
{
    int i, j;
    int y_size;
    int uv_size;
    unsigned char* p_yp;
    unsigned char* p_uv;
 
    unsigned char* p_ysp;
    unsigned char* p_u;
    unsigned char* p_v;
 
   //长宽条件前面已经控过了，这里不控；
    
    y_size = uv_size = width * height;
 
    p_yp = yuv422p;
    p_u  = p_yp + y_size;
    p_v  = p_u + width * height / 2;
 
    p_ysp = yuv422sp;
    p_uv = p_ysp + y_size;
    
    
    //y轴处理
    memcpy(p_ysp, p_yp, y_size);
    
    //uv轴处理
    for (j = 0, i = 0; j < uv_size; j+=2, i++)
    {
        p_uv[j] = p_u[i];
        p_uv[j+1] = p_v[i];
    }
    
}

/**
YUV422 planar(YV16) -->NV61(YUV422SP)
 
yyyy yyyy
vv
uu
->
yyyy yyyy
vu   vu
*/
void YV16_to_NV61(unsigned char* yuv422sp,
                         unsigned char* yuv422p,
                         int width, int height)
{
    int i, j;
    int y_size;
    int uv_size;
    unsigned char* p_yp;
    unsigned char* p_uv;
 
    unsigned char* p_ysp;
    unsigned char* p_u;
    unsigned char* p_v;
    
    if(width <= 0 || height<= 0)
    {
        printf("width and height of background image must be greater than 0.\n");
        exit (-1);
        
    }
    
    if (((width & 0x1) != 0) || ((height & 0x1) != 0))
    {
        printf("width and height of background image must be multiple of 2.\n");
        exit (-1);
       
    }
 
    y_size = uv_size = width * height;
 
    p_yp = yuv422p;
    p_v  = p_yp + y_size;
    p_u  = p_v + width * height / 2;
 
    p_ysp = yuv422sp;
    p_uv = p_ysp + y_size;
    
    
    //y轴处理
    memcpy(p_ysp, p_yp, y_size);
    
    //uv轴处理
    for (j = 0, i = 0; j < uv_size; j+=2, i++)
    {
        p_uv[j] = p_v[i];
        p_uv[j+1] = p_u[i];
    }
}
